package com.ea.eadp.nexus.test.pageDefinition;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;

import com.ea.eadp.nexus.test.common.PageOperation;
import com.ea.eadp.nexus.test.common.TestUtil;
import com.ea.nova.test.client.SystemPropertiesHelper;

/**
 * User: woodywu
 */
public class BasePage {
    public static final String baseUri = TestUtil.BaseConnectURI();

    protected String identifierId = null;
    protected String operationWindowHandle = null;
    protected long timeout = 0;
    protected Log log;
    protected WebDriver driver;

    public BasePage(WebDriver driver, Class cla) {
        this.driver = driver;
        log = LogFactory.getLog(cla);
        timeout = Long.parseLong(SystemPropertiesHelper.instance().getProperty("const.pageload.timeout", "30"));
        operationWindowHandle = driver.getWindowHandle();
    }

    public String getOperationWindowHandle() {
        return operationWindowHandle;
    }

    public void setOperationWindowHandle(String targetWindowHandle) {
        operationWindowHandle = targetWindowHandle;
    }

    public boolean getStatusForCheckBox(String elementID) {
        driver.switchTo().window(operationWindowHandle);
        return driver.findElement(By.id(elementID)).isSelected();
    }

    public String getElementStringByXPath(String xpath) {
        return getElementString(By.xpath(xpath));
    }

    public String getElementString(By by) {
        driver.switchTo().window(operationWindowHandle);
        WebDriverWait wait = new WebDriverWait(driver, 30, 1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(by));
        return driver.findElement(by).getText().trim();
    }

    public String getPageTitle() {
        driver.switchTo().window(operationWindowHandle);
        return driver.getTitle();
    }

    public void waitForWebElementPresent(By by) {
        WebDriverWait wait = new WebDriverWait(driver,timeout,1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }

    public void waitForWebElementNotPresent(By by) {
        WebDriverWait wait = new WebDriverWait(driver, timeout);
        wait.until(ExpectedConditions.invisibilityOfElementLocated(by));
    }

    public void clearInput(String elementId) {
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        jse.executeScript("$(\"#" + elementId + "\").val('');");
    }

    public void sendInput(String elementId, String keys) {
        clearInput(elementId);
        sendInput(driver.findElement(By.id(elementId)), keys);
    }

    public void validatePageContent(String path, String regex) throws Exception {
        PageOperation.WebDriverWaitByXpath(driver, path);
        String content = driver.findElement(By.xpath(path)).getText();
        if (!content.contains(regex) && !content.matches(getContainsRegex(regex))) {
            throw new Exception("expected [" + regex + "] but found [" + content + "]");
        }
    }

    private void sendInput(WebElement element, CharSequence keys) {
        element.sendKeys(keys);
    }

    private String uri;

    public void navigate() {
        if(getUri() != null) {
            driver.switchTo().window(operationWindowHandle);
            log.info(getUri());
            driver.navigate().to(getUri());
        }
    }

    public void navigate(String uri) {
        this.uri = uri;
        navigate();
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    protected String getContainsRegex(String value) {
        return (value.startsWith("^") ? "" : "(?s).*") + value + (value.endsWith("$") ? "" : "(?s).*");
    }

    protected void validateErrorMassage(final String errorMessageId, final String errorMessage) {
        PageOperation.WebDriverWait(driver, errorMessageId);
        Assert.assertEquals(driver.findElement(By.id(errorMessageId)).getText(), errorMessage);
    }
}
